package org.ace.view
{
	import Ace.roles;
	
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.getTimer;
	
	import org.ace.astar.AStar;
	import org.ace.astar.Grid;
	import org.ace.astar.MapDataUtils;
	import org.ace.astar.WayPoint;
	import org.ace.communicate.MessageReceived;
	import org.ace.model.MyModel;
	import org.ace.model.RoleModel;
	import org.ace.model.SocketModel;
	import org.ace.protocol.MapProtocol;
	import org.ace.protocol.Protocol;

	public class GameSceneHandler extends Sprite
	{

		private var role:MovieClip;
		private static var scene:GameSceneHandler;
		private var load:URLLoader=new URLLoader();
		private var l:Loader;
		private var grid:Grid;
		private var bg:Sprite=new Sprite();
		private var rc:Sprite=new Sprite();
		private var zz:Sprite=new Sprite();
		private var gridArray:Array;
		private var w:int=16;
		private var h:int=16;
		public var mapType:int;

		//场景角色对象数组
		private var roleArray:Array=new Array();
		private var mapId:int;
		public function GameSceneHandler()
		{
			addChild(bg);
			addChild(rc);
			addChild(zz);		
			
		}
		public static function getScene():GameSceneHandler{
			if(scene==null){
				scene=new GameSceneHandler();
			}
			return scene;
		}
		public function process(message:SocketModel):void{
			switch(message.command){
				case MapProtocol.enter_sres:
					enterSres(message.message as Array);
					break;
				case MapProtocol.enter_bro:
					enterBro(message.message);
					break;
				case MapProtocol.move_bro:
					move(message.message);
					break;
				case MapProtocol.leave_bro:
					leave(message.message);
					break;
				case MapProtocol.send_message_bro:
					IMHandler.getIm().mapMessage(message.message.toString());
					break;
				case MapProtocol.leave_battle_bro:
					break;
				case MapProtocol.on_battle_bro:
						for(var i:int=0;i<roleArray.length;i++){
							var rm:RoleModel=roleArray[i];
							if(message.message as int==rm.id){
								if(message.message as int!=MyModel.id){
									rm.onBattle(false);
								}else{
									rm.onBattle(true);
								}
							}
						}
					
					break;
			}
		}
		public function leave(message:Object):void{
			var rId:int=message as int;
			for(var i:int=0;i<roleArray.length;i++){
				var rm:RoleModel=roleArray[i];
				if(rId==rm.id){
					rm.delet();
					roleArray.splice(i,1);
					return;
				}
			}
		}
		public function move(message:Object):void{
			var rId:int=message.id;
			var path:Array=message.path;
			for(var i:int=0;i<roleArray.length;i++){
				var rm:RoleModel=roleArray[i];
				if(rId==rm.id){
					rm.move(path,grid);
					return;
				}
			}
		}
		public function enterBro(r:Object):void{
			var rm:RoleModel=new RoleModel();
			rm.attack=r.attack;
			rm.id=r.id;
			rm.mname==r.name;
			rm.model==r.model;
			rm.sp=new roles();
			rm.mx=r.x;
			rm.my=r.y;
			rm.sp.x=r.x;
			rm.sp.y=r.y;
			rm.sp.gotoAndStop(7);
			rc.addChild(rm.sp);
			roleArray.push(rm);
		}
		
		public function enterSres(rs:Array):void{
			for(var i:int=0;i<rs.length;i++){
				var rm:RoleModel=new RoleModel();
				rm.attack=rs[i].attack;
				rm.id=rs[i].id;
				rm.mname==rs[i].name;
				rm.model==rs[i].model;
				rm.sp=new roles();
				rm.mx=rs[i].x;
				rm.my==rs[i].y;
				rm.sp.x=rs[i].x;
				rm.sp.y=rs[i].y;
				rm.sp.gotoAndStop(7);
				rc.addChild(rm.sp);
				roleArray.push(rm);
				if(rm.id==MyModel.id){
					role=rm.sp;					
				}
			}
			load.dataFormat=URLLoaderDataFormat.BINARY;
			load.addEventListener(Event.COMPLETE,onLoad);
			load.addEventListener(ProgressEvent.PROGRESS,loading);
			load.addEventListener(IOErrorEvent.IO_ERROR,onError);
			Loading.getInstance().addLoading();
			Loading.getInstance().setBody("正在加载地图数据");
			load.load(new URLRequest("res/map/map"+MyModel.mapId+".txt"));
		}
		public function loading(e:ProgressEvent):void{
			Loading.getInstance().setIng((e.bytesLoaded/e.bytesTotal*100).toString());
		}
		/////////////////下面开始地图加载部分//////////////////////////////
		public function onLoad(e:Event):void{
			load.removeEventListener(ProgressEvent.PROGRESS,loading);
			load.removeEventListener(Event.COMPLETE,onLoad);
			var s:String=MapDataUtils.getInstance().dataToString(load.data);
			grid=MapDataUtils.getInstance().parse(s);		
			mapType=grid.type;
			l=new Loader();
			l.contentLoaderInfo.addEventListener(Event.COMPLETE,onImg);
			l.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onError);
			l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,loading);
			Loading.getInstance().setBody("正在加载地图背景");
			l.load(new URLRequest("res/map/map"+MyModel.mapId+".swf"));
		}
		public function onImg(e:Event):void{			
			l.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,loading);
			l.contentLoaderInfo.removeEventListener(Event.COMPLETE,onImg);
			l.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,onError);
			var myclass:Class =l.contentLoaderInfo.applicationDomain.getDefinition("org.ace.map") as Class;
			bg.addChild(new Bitmap(new myclass(0,0)));
			l=new Loader();
			l.contentLoaderInfo.addEventListener(Event.COMPLETE,onZZ);
			l.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onError);
			l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,loading);
			Loading.getInstance().setBody("正在加载地图遮罩");
			l.load(new URLRequest("res/map/map"+MyModel.mapId+"z.png"));
		}
		public function onZZ(e:Event):void{
			l.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,loading);
			l.contentLoaderInfo.removeEventListener(Event.COMPLETE,onZZ);
			l.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,onError);
			zz.addChild(l);
			if(-(role.x-(960/2))>0){
				scene.x=0;
			}else if(-(role.x-(960/2))-960<-scene.width){
				scene.x=-GameSceneHandler.getScene().width+960;
			}else{
				GameSceneHandler.getScene().x=-(role.x-(960/2));
				
			}
			if(-(role.y-(560/2))>0){
				scene.y=0;
			}else if(-(role.y-(560/2))-560<-scene.height){
				scene.y=-GameSceneHandler.getScene().height+560;
			}else{
				scene.y=-(role.y-(560/2));
				
			}
			this.addEventListener(MouseEvent.CLICK,onClick);
			Loading.getInstance().removeLoading();
			IMHandler.getIm().visible=true;
			MyGameDemo.view.addChild(GameSceneHandler.getScene());
		}
		public function onClick(e:MouseEvent):void{
			var gridArray:Array=findPath(role.x,role.y,e.stageX-GameSceneHandler.getScene().x,e.stageY-GameSceneHandler.getScene().y);
			if(gridArray.length>0){
				MessageReceived.getMessageReceived().write(Protocol.TYPE_MAP,MyModel.mapId,MapProtocol.move_creq,gridArray);
			}
		}
		public function resetRolez():void{
			var lr:Array=new Array();
			for(var i:int=0;i<roleArray.length;i++){
				lr.push(roleArray[i].sp);
			}
			lr.sortOn('y',Array.NUMERIC);
			for(i=0;i<lr.length;i++){
				var r:MovieClip=lr[i];
				if(rc.getChildIndex(r)!=i){
					rc.swapChildren(rc.getChildAt(i),r);
				}
			}
		}
		/**
		 * 调用寻路 获得真实节点
		 */
		public function findPath(startX:Number, startY:Number, targetX:Number, targetY:Number):Array 
		{ 
			
			if (grid != null && grid.numCols > 0 && grid.numRows > 0) 
			{ 
				//unit效率比Math.floor高 
				var gridX:uint = AStar.isoToGrid(startX, w); 
				var gridY:uint = AStar.isoToGrid(startY, h); 
				grid.setStartNode(gridX, gridY); 
				
				gridX = AStar.isoToGrid(targetX, w); 
				gridY = AStar.isoToGrid(targetY, h); 
				grid.setEndNode(gridX, gridY); 
			} 
			else return []; 
			
			var optimizePath:Array = new Array(); 
			
			if(grid.startNode == grid.endNode)//小距离移动 
			{ 
				optimizePath.push(new WayPoint(targetX, targetY)); 
				return optimizePath; 
			} 
			if(AStar.getInstance().findPath(grid)) 
			{ 
				var path:Array = AStar.getInstance().optimizePath(); 
				
				// 去掉起始节点 可以解决多次走路时 由于网络延迟导致的漂移问题 
				if(path.length!=2)//只有两个节点时，说明可以直达，不止两个节点时，就要把路点计算成世界坐标 再丢进去 
				{ 
					path.shift(); 
					path.pop(); 
					
					for each(var wp:WayPoint in path) 
					{ 
						optimizePath.push(new WayPoint( 
							AStar.gridToIso(wp.x, w), 
							AStar.gridToIso(wp.y, h))); 
					} 
				} 
				optimizePath.push(new WayPoint(targetX, targetY)); 
			} 
			return optimizePath; 
		}
		/**
		 * 设置角色层是否可见
		 * */
		public function setRcV(value:Boolean):void{
			rc.visible=value;
		}
		
		public function onError(e:IOErrorEvent):void{
		}
		public function clear():void
		{
			for(var i:int=0;scene.rc.numChildren;){
				rc.removeChildAt(i);
			}
			scene.removeChild(rc);
			rc=null;
			bg.removeChildAt(0);
			scene.removeChild(bg);
			bg=null;
			zz.removeChildAt(0);
			scene.removeChild(zz);
			zz=null;
			roleArray.splice(0,roleArray.length);
			roleArray=null;
			scene.removeEventListener(MouseEvent.CLICK,onClick);
			scene.parent.removeChild(scene);
			scene=null;
		}
	}
}